/**
 * @author chj
 * 创建时间：2020年8月29日
 * 修改时间：2020年8月31日
 * --------------------
 * 设计模式：原型模式
 * 基本定义：不根据类而根据实例来生成实例的设计模式是原型模式（Prototype Pattern）。
 * 详细说明：
 * * Prototype模式中的“Prototype”有“原型”的意思。
 * * Prototype模式是指根据实例原型来生成新的实例。
 * * 在三种情况下，Prototype模式适用：
 * * - 对象种类繁多，无法将它们整合到一个类中。
 * * * 在这种情况下，需要处理的对象太多，如果将它们分别作为一个类，则必须要编写很多个类文件。
 * * - 难以根据类生成实例。
 * * * 在这种情况下，生成实例的过程太过复杂，很难根据类来生成实例。
 * * - 想解耦生成实例的框架与具体的类
 * * * 在这种情况下，想要让生成实例的框架不依赖于具体的类。
 * 示例说明：
 * * 该示例是一段将字符串放入方框中显示出来或是给字符串加下划线显示出来的简单程序。
 * * 含有的接口：Product
 * * - Product接口声明了抽象方法use和抽象方法createClone。
 * * 含有的类：Manager、MessageBox、UnderlinePen、Main
 * * - Manager类调用Product接口的createClone抽象方法来复制实例。
 * * - MessageBox类实现将字符串放入方框中并使其显示出来。
 * * - UnderlinePen类实现给字符串加下划线并使其显示出来。
 * * - Main类用于测试程序行为。
 * * 登场角色：TemplatePrototype、ConcretePrototype、Client
 * * - TemplatePrototype角色决定了Prototype模式中复制现有实例来生成新实例的接口（API）。
 * * - ConcretePrototype角色决定了Prototype模式中复制现有实例来生成新实例的实现。
 * * - Client角色决定了Prototype模式中复制现有实例来生成新实例的使用。
 * 优点：无需为多种对象分别创建类；无需根据类生成实例；可解耦生成实例的框架和具体的类。
 * 缺点：无
 * --------------------
 * 思考：类名是束缚吗？
 * 内容：话说回来，在源程序中使用类名到底有什么问题呢？在代码中出现要使用的类的名字不是理所当然吗？
 * 解答：
 * * * 对于这个问题，让我们再回忆一下面向对象编程的目标之一：“作为组件复用”。
 * * * 在代码中出现要使用的类的名字并非总是坏事。不过，一旦在代码中出现要使用的类的名字，代码就无法与该类分离开来，也就无法实现组件复用。
 * * * 当然，可以通过替换源代码或是改变类名来解决这个问题。但是，此处所说的“作为组件复用”中不包含替换源代码。
 * * * 以Java来说，重要的是当手边只有class文件（.class）时，该类能否被复用。即使没有Java文件（.java）也能复用该类才是关键。
 * * * 当多个类必须紧密结合时，代码中出现这些类的名字是没有问题的。但是如果那些需要被独立出来作为组件复用的类的名字出现在代码中时，那就有问题了。
 * --------------------
 * 延伸阅读：clone方法和java.lang.Clonable接口
 * * * *
 * * - Java语言的clone
 * * * Java语言为开发者准备了用于复制实例的clone方法。请注意，要想调用clone方法，被复制对象的类必须实现java.lang.Clonable接口。
 * * * 不论是被复制对象的类实现java.lang.Clonable接口还是其某个父类实现java.lang.Clonable接口，亦或是被复制对象的类实现了java.lang.Clonable接口的子接口都可以。
 * * * 实现了java.lang.Clonable接口的类的实例可以调用clone方法进行复制，clone方法的返回值是复制出的新的实例。
 * * * clone方法内部所进行的处理是分配与要复制的实例同样大小的内存空间，接着将要复制的实例中的字段的值复制到所分配的内存空间中去。
 * * * 如果没有实现java.lang.Clonable接口的类调用了clone方法，则会在运行时抛出CloneNotSupportedException（不支持clone方法）异常。
 * * * 另外，java.lang包是被默认引入的，因此无需显式地引入java.lang包就可调用java.lang.Clonable接口。
 * * * *
 * * - clone方法是在哪里定义的？
 * * * clone方法定义在java.lang.Object中。因为java.lang.Object类是所有的Java类的父类，因此所有的Java类都继承了clone方法。
 * * * *
 * * - 需要实现java.lang.Clonable接口的哪些方法？
 * * * 提到Clonable接口，很容易让人误以为Clonable接口中声明了clone方法，其实这是错误的。
 * * * 在Clonable接口中并没有声明任何方法，它只是被用来标记“可以使用clone方法进行复制”。
 * * * 像这样用于标记功能的接口被称为标记接口（marker interface）。
 * * * *
 * * - clone方法进行的是浅复制
 * * * clone方法所进行的复制只是将被复制的实例的字段值直接复制到新的实例中。换言之它并没有考虑字段中所保存的实例的内容。
 * * * 例如：当字段保存的是数组时，如果使用clone方法进行复制，则只会复制该数组的引用，并不会一一复制数组中的元素。
 * * * 像上面这样的字段对字段的复制（field-to-field-copy），被称为浅复制（shallow copy）。
 * * * clone方法所进行的复制就是浅复制。
 * * * 当使用clone方法进行浅复制无法满足需求时，类的设计者可以实现重写clone方法，实现自己需要的复制功能。
 * * * 重写clone方法时，别忘了使用super.clone()来调用父类的clone方法。
 * * * 需要注意的是，clone方法只会进行复制，并不会调用被复制实例的构造函数。
 * * * 另外，对于在生成实例时需要进行特殊的初始化处理的类，需要自己去实现clone方法，在其内部进行特殊的初始化处理。
 * * * 详细信息请参见Java的API参考资料中java.lang.Object类的clone方法和java.lang.Clonable接口这两个相关条目。
 */
package prototype;